/*
 * SearchService.h
 *
 *  Created on: Mar 12, 2011
 *      Author: kmueller
 */

#ifndef SEARCHSERVICE_H_
#define SEARCHSERVICE_H_

#include "../core/Map.h"

#include <QThread>
#include <QMutex>
#include <QAbstractListModel>
#include <QVector>

#include "Helpers.h"

class ISearchModel {
public:
	virtual LabeledCoordinate get(int id) const = 0;
};

class SearchService: protected QThread {
Q_OBJECT

public:
	class SearchRequest {
	public:
		enum RequestType {
			CITY, STREET
		};

		virtual RequestType getType() = 0;
	};

	class SearchCityRequest: public SearchRequest {
	public:
		SearchCityRequest(QString& city, int country);
		RequestType getType();
		QString getString();
		int getCountryId();

	private:
		int country;
		QString city;
	};
	class SearchStreetRequest: public SearchRequest {
	public:
		SearchStreetRequest(QString& street, int cityId);
		RequestType getType();
		QString getString();
		int getCityId();

	private:
		int city;
		QString street;
	};

	class CityResult: public QAbstractListModel, public ISearchModel {
	public:
		CityResult(opennav::SearchCityResult& result, SearchService* parent);
		int rowCount(const QModelIndex &parent) const;
		QVariant data(const QModelIndex &index, int role) const;
		QVariant headerData(int section, Qt::Orientation orientation, int role) const;
		int getCityId(int id) const;
		LabeledCoordinate get(int id) const;
	private:
		QString getCityName(const opennav::City&) const;

		QVector<opennav::City> data_;
	};

	class StreetResult: public QAbstractListModel, public ISearchModel {
	public:
		StreetResult(opennav::SearchRoadResult& result, SearchService* parent);
		int rowCount(const QModelIndex &parent) const;
		QVariant data(const QModelIndex &index, int role) const;
		QVariant headerData(int section, Qt::Orientation orientation, int role) const;
		int getRoadId(int id) const;
		LabeledCoordinate get(int id) const;
	private:
		QString getStreetName(const opennav::Road& street) const;

		QVector<opennav::Road> data_;
	};
public:
	SearchService(opennav::Map* map);
	~SearchService();
	void searchCity(QString& city, int countryId);
	void searchStreet(QString& street, int cityId);

signals:
void resultAvailable(QAbstractListModel*);

private:
	void run();

	SearchRequest* request;
	QAbstractListModel* result;

	QMutex mutex;

	opennav::Map* map;

};

#endif /* SEARCHSERVICE_H_ */
